home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagn_r.zip / POINTERS.SWG / 0023_Match Strings in Array.pas < prev    next >
Pascal/Delphi Source File  |  1994-08-24  |  6KB  |  221 lines

  1.  
  2. {* Stack Research string for turbo pascal unit *}
  3. {* Public Domain, 21/07/94 by Mark Gauthier.   *}
  4. {* Fidonet 1:242/818.5, FM 101:190/805.5       *}
  5.  
  6. Unit Search;
  7.  
  8. { What for?, it use stack function to search for a matching string
  9.   in an array. }
  10.  
  11. Interface
  12.  
  13. Const
  14.  
  15.         MaxString : Word = 4096;
  16.         MaxStack  : Word = 500;
  17.  
  18. Var
  19.         StrAddr         : Array[1..4096] of Pointer;
  20.         { Addresse for all strings. }
  21.  
  22.         TotalStr        : Word;
  23.         { Curent strings number }
  24.  
  25.         StrFreq         : Array[1..4096] of Word;
  26.         { Search frequence for each string }
  27.  
  28.         procedure ClearAllStack;
  29.         { Clear stack.  You must call this procedure to tell unit
  30.           you will change the searchstring. }
  31.  
  32.         procedure AddString (S:String);
  33.         { Add a string in array, only if totalstr if < maxstring. }
  34.  
  35.         function  SearchString (S:String) : boolean;
  36.         { Search for a string, if stack is not clear previous search as
  37.           been made. Example: you search for 'ABC' and this function
  38.           return true.  If you search for 'ABCD' then this function
  39.           will go in stack and get all the old addr for 'ABC' and see
  40.           if 'D' is the next letter for the check strings.
  41.  
  42.           * This unit is usefull to build compression unit.
  43.         }
  44.  
  45. implementation
  46.  
  47. Var
  48.         SearchStr       : Pointer;
  49.         LastFound       : Word;
  50.         CurentStack     : Byte;
  51.         StackPos        : Array[1..2] of Word;
  52.         StackData       : Array[1..2,1..500] of Word;
  53.  
  54. {*===================================================================*}
  55.  
  56. { Return true is stack is empty }
  57. function StackIsEmpty:boolean;
  58. begin
  59.      StackIsEmpty := false;
  60.      if StackPos[CurentStack] = 0 then StackIsEmpty := true;
  61. end;
  62.  
  63. {*===================================================================*}
  64.  
  65. { Pop an element from stack }
  66. function MgPop:Word;
  67. begin
  68.      MgPop := 0;
  69.      If Not StackIsEmpty then
  70.      begin
  71.           MgPop := StackData[CurentStack, StackPos[CurentStack]];
  72.           Dec(StackPos[CurentStack]);
  73.      end;
  74. end;
  75.  
  76. {*===================================================================*}
  77.  
  78. { Push an element on stack }
  79. procedure MgPush(Number:word);
  80. var x:byte;
  81. begin
  82.      if CurentStack = 1 then x := 2 else x := 1;
  83.      If StackPos[x] < MaxStack then
  84.      begin
  85.           Inc(StackPos[x]);
  86.           StackData[x, StackPos[x]] := Number;
  87.      end;
  88. end;
  89.  
  90. {*===================================================================*}
  91.  
  92. { Clear the curent stack }
  93. procedure ClearStack;
  94. begin
  95.      StackPos[CurentStack] := 0;
  96. end;
  97.  
  98. {*===================================================================*}
  99.  
  100. { Inverse pop and push stack }
  101. procedure InverseStack;
  102. begin
  103.      ClearStack;
  104.      If CurentStack = 1 then CurentStack := 2 else CurentStack := 1;
  105. end;
  106.  
  107. {*===================================================================*}
  108.  
  109. { Compare SearchStr(global var) and DATA(parameter) }
  110. {$F+}
  111. function Compare(Data:Pointer):boolean;assembler;
  112. asm
  113.           push      bp
  114.           mov       bp,sp
  115.  
  116.           push      ds
  117.  
  118.           lds       si,SearchStr
  119.           lodsb
  120.           mov       cl,al
  121.           mov       ch,0
  122.  
  123.           les       di,[Bp+8]
  124.           inc       di
  125.  
  126.           mov       al,0
  127.           cld
  128.           repe      cmpsb
  129.           jne       @NotMatch
  130.           mov       al,1
  131.  
  132. @NotMatch:
  133.  
  134.           pop       ds
  135.           pop       bp
  136. end;
  137. {$F-}
  138.  
  139. {*===================================================================*}
  140.  
  141. { Search procedure execute this procedure if stack is not empty. }
  142. function SearchWhitPop:boolean;
  143. Var Start : Word;
  144. begin
  145.      SearchWhitPop := false;
  146.      While not StackIsEmpty do
  147.      begin
  148.           Start := MgPop;
  149.           if Compare(StrAddr[Start]) then
  150.           begin
  151.                 LastFound := Start;
  152.                 SearchWhitPop := true;
  153.                 MgPush(Start);
  154.                 Inc(StrFreq[Start]);
  155.           end;
  156.      end;
  157.      InverseStack;
  158. end;
  159.  
  160. {*===================================================================*}
  161.  
  162. { Search procedure execute this procedure if stack is empty. }
  163. function CompleteSearchPush:boolean;
  164. var i : word;
  165. begin
  166.      CompleteSearchPush := false;
  167.      For i := 1 to TotalStr do
  168.      begin
  169.           if Compare(StrAddr[i]) then
  170.           begin
  171.                 LastFound := i;
  172.                 CompleteSearchPush := true;
  173.                 MgPush(i);
  174.                 Inc(StrFreq[i]);
  175.           end;
  176.      end;
  177.      InverseStack;
  178. end;
  179.  
  180. {*===================================================================*}
  181.  
  182. { Public Search routine }
  183. function SearchString(S:String):boolean;
  184. begin
  185.      SearchStr := Addr(S);
  186.      If StackIsEmpty
  187.      then SearchString := CompleteSearchPush
  188.      else SearchString := SearchWhitPop;
  189. end;
  190.  
  191. {*===================================================================*}
  192.  
  193. { Add a string in heap }
  194. procedure AddString(S:String);
  195. begin
  196.      Inc(TotalStr);
  197.      GetMem(StrAddr[TotalStr], Length(S));
  198.      Move(S,StrAddr[TotalStr]^, Length(S)+1);
  199. end;
  200.  
  201. {*===================================================================*}
  202.  
  203. { Clear pop and push stack }
  204. procedure ClearAllStack;
  205. begin
  206.      InverseStack;
  207.      ClearStack;
  208. end;
  209.  
  210. {*===================================================================*}
  211.  
  212. { Unit Initialisation }
  213. var i : word;
  214. Begin
  215.      TotalStr    := 0;
  216.      CurentStack := 0;
  217.      StackPos[1] := 0;
  218.      StackPos[2] := 0;
  219.      for i := 1 to 4096 do StrFreq[i] := 0;
  220. End.
  221.